package ycl.common.utils;


import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.generator.FastAutoGenerator;
import com.baomidou.mybatisplus.generator.config.OutputFile;
import com.baomidou.mybatisplus.generator.config.TemplateType;
import ycl.common.base.controller.BaseController;
import ycl.common.base.entity.BaseEntity;
import ycl.common.base.mapper.BaseDao;
import ycl.common.base.service.BaseService;
import ycl.common.base.service.impl.BaseServiceImpl;

import java.io.*;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Scanner;

/**
 * spring cloud 代码生成工具, 使用时有两种选择:<br/><br/>
 * 一. 保证: <br/>
 * 1. 数据库命名: [个人/公司名] _ [模块] , 如: ycl_system <br/>
 * 2. 分模块命名: [个人/公司名] - [模块] , 如: ycl-system <br/>
 * -------------- <br/><br/>
 * <p>
 * 二. 修改代码 <br/>
 * 1. outputDirPrefix 定义时去掉 entityName <br/>
 * 2. moduleName 改成调用 scannerName() 方法输入
 *
 * @author: YCL
 * @date: 2022/01/19 22:32:02
 */
public class CodeGeneratorUtil {

	private static final String templatesPrefix = "/templates/";
	private static final String property = System.getProperty("user.dir");


//	public static void main(String[] args) throws IOException {
//		scannerName(null);
//		String sqlName = "ycl_system";
//		String[] split = sqlName.split("_");
//		String moduleName = sqlName.replaceAll("_", "-");
//
//		String firstName = split[0];
//		String secondName = split[1];
//		String packageName = firstName + "." + secondName;
//		String entityName = "\\" + moduleName + "\\" + moduleName + "-entity";
//		String dir = property + entityName + "\\src\\main\\java\\" + firstName + "\\" + secondName + "\\";
//		writeReq(dir);
//	}

	private static void writeReq(String dir) throws IOException {
		String outUrl = dir + "req\\";
		File inDir = new File(dir + "entity\\");
		File outDir = new File(outUrl);
		if (!outDir.exists())
			outDir.mkdirs();
		for (File file : inDir.listFiles()) {

			String inName = file.getName();
			String prefix = inName.split("\\.")[0];
			String className = prefix + "Req";
			File out = new File(outUrl + className + ".java");
			if (out.exists())
				continue;
			out.createNewFile();

			FileReader r = new FileReader(file);
			BufferedReader br = new BufferedReader(r);
			FileWriter w = new FileWriter(out);
			BufferedWriter bw = new BufferedWriter(w);
			String description = "";
			try {
				String s;
				while ((s = br.readLine()) != null) {
					if (s.startsWith("@ApiModel(")) {
						String s1 = s.replace("@ApiModel(", "{\"")
								.replaceAll("\\)", "}")
								.replaceAll(", ", ",\"")
								.replaceAll(" = ", "\":");
						JSONObject jsonObject = JSONObject.parseObject(s1);
						description = jsonObject.get("description") + "请求体";
						break;
					}
				}

				List<String> templates = templates(className, description);
				for (String t : templates) {
					bw.write(t);
					bw.newLine();
				}
			} finally {
				br.close();
				r.close();
				bw.close();
				w.close();
			}
		}
	}

	private static List<String> templates(String fileName, String description) {
		String script = description + "请求体";

		String[] strings = {
				"package ycl.base.req;",
				"import io.swagger.annotations.ApiModel;",
				"import lombok.Data;",
				"import lombok.EqualsAndHashCode;",
				"import lombok.experimental.Accessors;",
				"import ycl.common.models.req.BaseReq;",
				"/**",
				" * " + script,
				" *",
				" * @author ycl",
				" * @date 2022/6/27 0027 0:01:03",
				" */",
				"@EqualsAndHashCode(callSuper = true)",
				"@Data",
				"@Accessors(chain = true)",
				"@ApiModel(\"" + script + "\")",
				"public class " + fileName + " extends BaseReq {",
				"}",
		};
		return Arrays.asList(strings);
	}


	public static void main(String[] args) throws IOException {
		System.out.println(property);
		scannerName(null);
		String sqlName = scannerName("请输入数据库名");
		String[] split = sqlName.split("_");
		String moduleName = sqlName.replaceAll("_", "-");

		String firstName = split[0];
		String secondName = split[1];
		String packageName = firstName + "." + secondName;

		String serviceName = "\\" + moduleName + "\\" + moduleName + "-service";
		String entityName = "\\" + moduleName + "\\" + moduleName + "-entity";
		//String serviceName = moduleName + "-service";
		String outputDirPrefix = property + serviceName + "\\src\\main\\";
		FastAutoGenerator.create("jdbc:mysql://localhost:3306/" + sqlName + "?serverTimezone=Asia/Shanghai",
				"root",
				"0000")
				.globalConfig(builder -> {
					builder.author("ycl")               //作者
							.outputDir(outputDirPrefix + "java")    //输出路径(写到java目录)
							.enableSwagger()           //开启swagger
							.commentDate("yyyy-MM-dd HH:mm:ss");
					//.fileOverride();            //开启覆盖之前生成的文件
				})
				.packageConfig(builder -> builder.parent(packageName)//包名输出
						.entity("entity")//实体类位置
						.service("service")//逻辑层位置
						.serviceImpl("service.impl")//逻辑实现类位置
						.controller("controller")//控制器位置
						.mapper("mapper")//数据库层位置
						.xml("mapper")//xml位置
						//xml输出位置
						.pathInfo(Collections.singletonMap(
								OutputFile.mapperXml, outputDirPrefix + "resources\\mapper")))
				.strategyConfig(builder -> builder
						//实体类策略
						.entityBuilder()
						.formatFileName("%s")
						.superClass(BaseEntity.class)
						.enableLombok()
						.enableChainModel()
						.logicDeleteColumnName("deleted")
						.enableTableFieldAnnotation()
						.enableActiveRecord()

						//控制器策略
						.controllerBuilder()
						.formatFileName("%sController")
						.superClass(BaseController.class)
						.enableRestStyle()

						//数据库策略
						.mapperBuilder()
						.enableBaseResultMap()  //生成通用的resultMap
						.superClass(BaseDao.class)
						.enableBaseColumnList()
						.formatMapperFileName("%sMapper")
						.enableMapperAnnotation()
						.formatXmlFileName("%sMapper")

						//逻辑层策略
						.serviceBuilder()
						.superServiceClass(BaseService.class)
						.formatServiceFileName("%sService")
						.superServiceImplClass(BaseServiceImpl.class)
						.formatServiceImplFileName("%sServiceImpl")
				)
				.templateConfig(builder -> builder.disable(TemplateType.ENTITY)
						.entity(templatesPrefix + "entity.java")
						.service(templatesPrefix + "service.java")
						.serviceImpl(templatesPrefix + "serviceImpl.java")
						.mapper(templatesPrefix + "mapper.java")
						.mapperXml(templatesPrefix + "mapper.xml")
						.controller(templatesPrefix + "controller.java"))
				.execute();

		String reqDir = outputDirPrefix + "java\\" + firstName + "\\" + secondName + "\\";
		writeReq(reqDir);
	}


	private static String scannerName(String tip) {
		if (StrUtil.isBlank(tip))
			return null;
		System.out.println(tip);
		Scanner sc = new Scanner(System.in);
		String s = sc.nextLine().replaceAll(" ", "");
		sc.close();
		return s;
	}
}
